/**
 * 
 */
package com.dalonedrow.engine.ui.impl;

import java.util.ArrayList;

import com.dalonedrow.engine.sprite.base.SimpleDimension;
import com.dalonedrow.engine.sprite.base.SimpleRectangle;
import com.dalonedrow.engine.sprite.base.SpriteBase;
import com.dalonedrow.engine.systems.JOGLErrorHandler;
import com.dalonedrow.engine.systems.Sprite;
import com.dalonedrow.engine.systems.base.Action;
import com.dalonedrow.engine.ui.base.GuiComponent;
import com.dalonedrow.engine.ui.base.GuiSelectable;
import com.dalonedrow.engine.ui.base.GuiTextItemImpl;
import com.dalonedrow.engine.ui.base.border.GuiBorder;
import com.dalonedrow.globalvariables.constants.hq.GlobalConstants;

/**
 * Button borders are like rings on a tree trunk.<br>
 * _______________________________<br>
 * | highlight/selection border |<br>
 * | _________________________ |<br>
 * | | standard border | |<br>
 * | | _____________________ | |<br>
 * | | | button text/image | | |<br>
 * | | --------------------- | |<br>
 * | ------------------------- |<br>
 * -------------------------------<br>
 * @author Donald
 */
public class Button extends GuiTextItemImpl implements GuiSelectable {
	/** the list of actions to perform when the item is selected. */
	private ArrayList<Action>	actions				= new ArrayList<Action>();
	/** the order of precedence in which the borders are rendered. */
	private int					borderPrecedence	= GuiComponent.BORDER_FIRST;
	/** the sprite rendered when the {@link Button} is disabled. */
	private SpriteBase			disabledSprite;
	/** the sprite rendered when the {@link Button} is disabled. */
	private SpriteBase			enabledSprite;
	/** the highlight border. */
	private GuiBorder			highlightBorder;
	/** flag indicating whether the <code>Button</code> is highlighted. */
	private boolean				highlighted			= false;
	/** the <code>Button</code>'s hotspot. */
	private SimpleRectangle	hotspot;
	/** the <code>Button</code>'s preferred size. */
	private SimpleDimension			preferredSize		= new SimpleDimension(0, 0);
	/** the select border. */
	private GuiBorder			selectBorder;
	/** flag indicating whether the <code>Button</code> is selected. */
	private boolean				selected			= false;
	/** the sprite rendered when the {@link Button} is selected. */
	private SpriteBase			selectedSprite;
	/**
	 * Gets the selectedSprite 
	 * @return {@link SpriteBase}
	 */
	public SpriteBase getSelectedSprite() {
		return selectedSprite;
	}
	/**
	 * Sets the selectedSprite
	 * @param selectedSprite the selectedSprite to set
	 */
	public void setSelectedSprite(SpriteBase val) {
		this.selectedSprite = val;
	}
	/**
	 * Creates a new instance of Button.java.
	 * @param sprite the {@link Sprite} displayed by this {@link Button}
	 */
	public Button(final SpriteBase sprite) {
		this(null, null);
		super.setSprite(sprite);
		getPreferredSize();
	}
	/**
	 * Creates a new instance of Button.java with text.
	 * @param newFont the {@link GameFont} used
	 * @param newText the text to display
	 */
	public Button(final String font, final String newText) {
		super(font, newText);
		// super.setPreferredWidth(GlobalConstants.SCREEN_WIDTH);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void addAction(final Action action) {
		actions.add(action);
	}
	/**
	 * {@inheritDoc}
	 */
	public void animate() {
		// TODO Auto-generated method stub

	}
	/** Assigns the selection flag. */
	public void assignSelection() {
		selected = true;
	}
	public void assignSpriteFlag(final long flag) {
		super.getTextGroup().assignFlag(flag);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void clearActions() {
		actions.clear();
	}
	public void clearSpriteFlags() {
		super.getTextGroup().clearFlags();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public SimpleRectangle getHotSpot() {
		SimpleRectangle rect = hotspot;
		if (rect == null) {
			double x = super.getPosition().getX();
			double y = super.getPosition().getY();
			double w = getPreferredSize().width;
			double h = getPreferredSize().height;
			// the border is not clickable
			if (super.getBorder() != null) {
				x += super.getBorder().getInsets().left;
				w -= super.getBorder().getInsets().left;
				w -= super.getBorder().getInsets().right;
				y += super.getBorder().getInsets().bottom;
				h -= super.getBorder().getInsets().top;
				h -= super.getBorder().getInsets().bottom;
			}
			if (highlightBorder != null) {
				x += highlightBorder.getInsets().left;
				w -= highlightBorder.getInsets().left;
				w -= highlightBorder.getInsets().right;
				y += highlightBorder.getInsets().bottom;
				h -= highlightBorder.getInsets().top;
				h -= highlightBorder.getInsets().bottom;
			}
			if (selectBorder != null) {
				x += selectBorder.getInsets().left;
				w -= selectBorder.getInsets().left;
				w -= selectBorder.getInsets().right;
				y += selectBorder.getInsets().bottom;
				h -= selectBorder.getInsets().top;
				h -= selectBorder.getInsets().bottom;
			}
			rect = new SimpleRectangle((int) x, (int) y, (int) w, (int) h);
		}
		return rect;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public SimpleDimension getPreferredSize() {
		if (preferredSize.width == 0
				|| preferredSize.height == 0) {
			// ***************************************
			// ** CALCULATE THE SIZE OF THE UI WIDGET
			// ***************************************
			int pWidth = getPreferredWidth();
			// remember if the preferred width was ever set
			boolean prefWidthSet = true;
			if (pWidth == 0) {
				pWidth = GlobalConstants.SCREEN_WIDTH;
				prefWidthSet = false;
			}
			int w = 0, h = 0;
			// add border insets to width and height
			if (super.getBorder() != null) {
				w = super.getBorder().getInsets().left;
				w += super.getBorder().getInsets().right;
				h = super.getBorder().getInsets().top;
				h += super.getBorder().getInsets().bottom;
				pWidth -= super.getBorder().getInsets().left;
				pWidth -= super.getBorder().getInsets().right;
			}
			if (super.isDebug()) {
				System.out.println(this+" w1="+w);
			}
			// add highlight and selection border insets to width and height
			int outerBorderWidth = 0, obh = 0;
			if (highlightBorder != null) {
				outerBorderWidth += highlightBorder.getInsets().left;
				outerBorderWidth += highlightBorder.getInsets().right;
				obh += highlightBorder.getInsets().top;
				obh += highlightBorder.getInsets().bottom;
			}
			if (selectBorder != null) {
				outerBorderWidth = Math.max(outerBorderWidth,
						selectBorder.getInsets().left
								+ selectBorder.getInsets().right);
				obh = Math.max(obh,
						selectBorder.getInsets().top
								+ selectBorder.getInsets().bottom);
			}
			w += outerBorderWidth;
			h += obh;
			pWidth -= outerBorderWidth;
			if (super.isDebug()) {
				System.out.println(this+" w2="+w);
			}
			// remove insets from preferred width before sizing text
			pWidth -= super.getInsets().left;
			pWidth -= super.getInsets().right;
			// add label insets to width and height
			w += super.getInsets().left + super.getInsets().right;
			h += super.getInsets().top + super.getInsets().bottom;
			if (super.isDebug()) {
				System.out.println(this+" w3="+w);
			}
			if (super.getSprite() != null) {
				// if this is an image label,
				// add image size to label width and height
				w += super.getSprite().getWidth();
				h += super.getSprite().getHeight();
				if (super.isDebug()) {
					System.out.println(this+" w4="+w);
				}
			} else {
				// this is a text label
				try {
					// ***************************************
					// ** ADD TEXT TO THE SPRITE GROUP
					// ***************************************
					sizeText();
					if (super.getTextGroup() != null
							&& super.getText() != null
							&& super.getText().length() > 0) {
						Sprite.getInstance().computeFullStats(
								super.getTextGroup());
					}
				} catch (Exception ex) {
					JOGLErrorHandler.getInstance().fatalError(ex);
				}
				w += getTextWidth();
				h += getTextHeight();
			}
			pWidth = w;
			if (super.getBorder() != null) {
				pWidth -= super.getBorder().getInsets().left;
				pWidth -= super.getBorder().getInsets().right;
			}
			pWidth -= outerBorderWidth;
			pWidth -= super.getInsets().left;
			pWidth -= super.getInsets().right;
			if (prefWidthSet) {
				w = getPreferredWidth();
			}
			if (super.getMinimumHeight() > 0) {
				h = Math.max(h, super.getMinimumHeight());
			}
			if (super.getMaximumHeight() > 0) {
				h = Math.min(h, super.getMaximumHeight());
			}
			if (super.getMinimumWidth() > 0) {
				w = Math.max(w, super.getMinimumWidth());
			}
			if (super.getMaximumWidth() > 0) {
				w = Math.min(w, super.getMaximumWidth());
			}
			if (super.isDebug()) {
				System.out.println(this+" w5="+w);
			}
			preferredSize.width = w;
			preferredSize.height = h;
			// set border sizes based on order
			switch (borderPrecedence) {
			case GuiComponent.BORDER_FIRST:
				int internalW = 0,
				internalH = 0;
				// outside border gets button full size
				if (super.getBorder() != null) {
					super.getBorder().setPreferredSize(w, h);
					internalW = super.getBorder().getInsets().left
							+ super.getBorder().getInsets().right;
					internalH = super.getBorder().getInsets().top
							+ super.getBorder().getInsets().bottom;
				}
				// inside borders get size of button
				// less the first border insets
				if (highlightBorder != null) {
					highlightBorder.setPreferredSize(
							w - internalW,
							h - internalH);
				}
				if (selectBorder != null) {
					selectBorder.setPreferredSize(
							w - internalW,
							h - internalH);
				}
				break;
			default:
				internalW = 0;
				internalH = 0;
				if (highlightBorder != null) {
					highlightBorder.setPreferredSize(w, h);
					internalW = highlightBorder.getInsets().left
							+ highlightBorder.getInsets().right;
					internalH = highlightBorder.getInsets().top
							+ highlightBorder.getInsets().bottom;
				}
				if (selectBorder != null) {
					selectBorder.setPreferredSize(w, h);
					internalW = Math.max(internalW,
							selectBorder.getInsets().left
									+ selectBorder.getInsets().right);
					internalH = Math.max(internalH,
							selectBorder.getInsets().top
									+ selectBorder.getInsets().bottom);
				}
				if (super.getBorder() != null) {
					super.getBorder().setPreferredSize(
							w - internalW,
							h - internalH
							);
				}
				break;
			}
			try {
				// ***************************************
				// ** POSITION ALL TEXT
				// ***************************************
				if (super.getPosition() != null) {
					positionBorders();
					if (super.getSprite() != null) {
						double x = super.getPosition().getX();
						double y = super.getPosition().getY();
						double z = super.getPosition().getZ();
						if (super.isDebug()) {
							System.out.println(this+" x1=" + x);
						}
						if (super.getBorder() != null) {
							x += super.getBorder().getInsets().left;
							y += super.getBorder().getInsets().bottom;
						}
						if (super.isDebug()) {
							System.out.println(this+" x2=" + x);
						}
						int innerLeftInset = 0, innb = 0;
						if (highlightBorder != null) {
							innerLeftInset = highlightBorder.getInsets().left;
							innb = highlightBorder.getInsets().bottom;
						}
						if (super.isDebug()) {
							System.out.println(this+" innerLeftInset=" + innerLeftInset);
						}
						if (selectBorder != null) {
							innerLeftInset = Math.max(innerLeftInset,
									selectBorder.getInsets().left);
							innb = Math.max(innb,
									selectBorder.getInsets().bottom);
						}
						x += innerLeftInset;
						y += innb;
						if (super.isDebug()) {
							System.out.println(this+" x3=" + x);
						}
						x += super.getInsets().left;
						y += super.getInsets().bottom;
						if (super.isDebug()) {
							System.out.println(this+" x4=" + x);
						}
						super.getSprite().setPosition(x, y, z);
					}
				}
				positionText();
			} catch (Exception ex) {
				JOGLErrorHandler.getInstance().fatalError(ex);
			}
		}
		return preferredSize;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isHighlightable() {
		return super.isActive();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isHighlighted() {
		return highlighted;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isInHotSpot(final float x, final float y) {
		boolean isIn = false;
		if (isActive() && isVisible() && isSelectable()) {
			isIn = getHotSpot().contains((int) x, (int) y);
		}
		return isIn;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isSelectable() {
		return super.isActive();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isSelected() {
		return selected;
	}
	/**
	 * {@inheritDoc}
	 */
	public void move() {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean onHighlight(final boolean value) {
		highlighted = value;
		boolean cando = true;
		if (!highlighted || !super.isActive() || !super.isVisible()) {
			cando = false;
			highlighted = false;
		}
		return cando;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean onSelect() {
		boolean done = false;
		// the item was selected. was this a valid option?
		if (super.isActive() && super.isVisible()) {
			selected = true;
			performAction();
			done = true;
		}
		return done;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void performAction() {
		for (int i = 0; i < actions.size(); i++) {
			actions.get(i).performAction();
		}
	}
	private void positionBorders() {
		if (super.getPosition() != null) {
			switch (borderPrecedence) {
			case GuiComponent.BORDER_FIRST:
				int left = 0,
				bottom = 0;
				// position outside border at button position
				if (super.getBorder() != null) {
					super.getBorder().setPosition(
							super.getPosition().getX(),
							super.getPosition().getY(),
							super.getPosition().getZ()
							);
					left = super.getBorder().getInsets().left;
					bottom = super.getBorder().getInsets().bottom;
				}
				// position select, highlight borders inside 1st border
				if (selectBorder != null) {
					selectBorder.setPosition(
							super.getPosition().getX() + left,
							super.getPosition().getY() + bottom,
							super.getPosition().getZ()
									+ GlobalConstants.CHILD_STEP
							);
				}
				if (highlightBorder != null) {
					highlightBorder.setPosition(
							super.getPosition().getX() + left,
							super.getPosition().getY() + bottom,
							super.getPosition().getZ()
									+ GlobalConstants.CHILD_STEP
							);
				}
				break;
			default:
				left = 0;
				bottom = 0;
				// position select, highlight
				// borders at button position
				if (selectBorder != null) {
					selectBorder.setPosition(
								super.getPosition().getX(),
								super.getPosition().getY(),
								super.getPosition().getZ()
								);
					left = selectBorder.getInsets().left;
					bottom = selectBorder.getInsets().bottom;
				}
				if (highlightBorder != null) {
					highlightBorder.setPosition(
								super.getPosition().getX(),
								super.getPosition().getY(),
								super.getPosition().getZ()
								);
					left = Math.max(left,
								highlightBorder.getInsets().left);
					bottom = Math.max(bottom,
								highlightBorder.getInsets().bottom);
				}
				// position border at inside
				// highlight, select position
				if (super.getBorder() != null) {
					super.getBorder().setPosition(
								super.getPosition().getX() + left,
								super.getPosition().getY() + bottom,
								super.getPosition().getZ()
										+ GlobalConstants.CHILD_STEP
								);
				}
				break;
			}
		}
	}
	/**
	 * Positions all text within the {@link GuiTextItem}'s boundaries.
	 * @throws Exception if an error occurs
	 */
	private void positionText() throws Exception {
		if (super.getPosition() != null
				&& super.getTextGroup() != null) {
			super.getTextGroup().clearFloatStore();
			int height = getPreferredSize().height;
			// text position is set relative to component position
			// when component position changes, the text position doesn't need
			// to be re-calibrated
			double x = 0, y = 0;
			// move in from border insets
			if (super.getBorder() != null) {
				x += super.getBorder().getInsets().left;
				y += super.getBorder().getInsets().bottom;
				height -= super.getBorder().getInsets().top;
				height -= super.getBorder().getInsets().bottom;
			}
			if (selectBorder != null || highlightBorder != null) {
				int outerBorderLeft = 0, outerBorderBottom = 0, outerBorderTop = 0;
				if (highlightBorder != null) {
					outerBorderLeft = highlightBorder.getInsets().left;
					outerBorderBottom = highlightBorder.getInsets().bottom;
					outerBorderTop = highlightBorder.getInsets().top;
				}
				if (selectBorder != null) {
					outerBorderLeft = Math.max(outerBorderLeft,
							selectBorder.getInsets().left);
					outerBorderBottom = Math.max(outerBorderBottom,
							selectBorder.getInsets().bottom);
					outerBorderTop = Math.max(outerBorderTop,
							selectBorder.getInsets().top);
				}
				x += outerBorderLeft;
				y += outerBorderBottom;
				height -= outerBorderTop;
				height -= outerBorderBottom;
			}
			// move up from label insets
			x += super.getInsets().left;
			y += super.getInsets().bottom;
			height -= super.getInsets().top;
			height -= super.getInsets().bottom;
			super.getTextGroup().setPosition(
					x,
					y,
					super.getPosition().getZ() + GlobalConstants.CHILD_STEP,
					height,
					super.getVerticalAlignment()
					);
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void prepareForRendering() throws Exception {
		// TODO Auto-generated method stub
		super.prepareForRendering();
		// draw highlight
		if (highlighted
				&& highlightBorder != null) {
			highlightBorder.prepareForRendering();
		}
		// draw selection
		if (selected
				&& selectBorder != null) {
			selectBorder.prepareForRendering();
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeHighlight() {
		highlighted = false;
	}
	/** Removes the selection flag. */
	public void removeSelection() {
		selected = false;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setActive(final boolean isActive) {
		super.setActive(isActive);
		final int three = 3;
		if (highlighted
				&& !isActive) {
			// clear highlights when no longer active
			highlighted = false;
		}
		if (!isActive) {
			if (super.getTextGroup() != null
					&& super.getInactiveColor() != null) {
				float[] colors = super.getInactiveColor().getComponents(null);
				if (super.getTextGroup().getRed() != colors[0]
						|| super.getTextGroup().getBlue() != colors[1]
						|| super.getTextGroup().getGreen() != colors[2]
						|| super.getTextGroup().getGreen() 
						!= colors[three]) {
					super.getTextGroup().setRed(colors[0]);
					super.getTextGroup().setGreen(colors[1]);
					super.getTextGroup().setBlue(colors[2]);
					super.getTextGroup().setAlpha(colors[three]);
					super.getTextGroup().clearFloatStore();
				}
			} else if (super.getTextGroup() != null) {
				if (super.getTextGroup().getRed() != GlobalConstants.DIV_2) {
					super.getTextGroup().setRed(GlobalConstants.DIV_2);
					super.getTextGroup().setGreen(GlobalConstants.DIV_2);
					super.getTextGroup().setBlue(GlobalConstants.DIV_2);
					super.getTextGroup().clearFloatStore();
				}
			}
		} else if (super.getTextGroup() != null) {
			float[] colors = super.getColor().getComponents(null);
			if (super.getTextGroup().getRed() != colors[0]
					|| super.getTextGroup().getBlue() != colors[1]
					|| super.getTextGroup().getGreen() != colors[2]
					|| super.getTextGroup().getAlpha() 
					!= colors[three]) {
				super.getTextGroup().setRed(colors[0]);
				super.getTextGroup().setGreen(colors[1]);
				super.getTextGroup().setBlue(colors[2]);
				super.getTextGroup().setAlpha(colors[three]);
				super.getTextGroup().clearFloatStore();
			}
		}
	}
	/**
	 * Sets the borderPrecedence.
	 * @param value the borderPrecedence to set
	 * @throws Exception if the value is in invalid
	 */
	public void setBorderPrecedence(final int value)
			throws Exception {
		if (value > GuiComponent.BORDER_FIRST
				|| value < GuiComponent.HIGHLIGHT_FIRST) {
			throw new Exception("Invalid assigment for border precedence");
		}
		borderPrecedence = value;
		preferredSize.width = 0;
		preferredSize.height = 0;
		getPreferredSize();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean setFocus(final float x, final float y) {
		// TODO Auto-generated method stub
		return false;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setHighlightable(final boolean isHighlightable) {
		// TODO Auto-generated method stub

	}
	/**
	 * Sets the highlightBorder.
	 * @param border the highlightBorder to set
	 */
	@Override
	public void setHighlightBorder(final GuiBorder border) {
		highlightBorder = border;
		preferredSize.width = 0;
		preferredSize.height = 0;
		getPreferredSize();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setHotSpot(final SimpleRectangle value) {
		hotspot = value;
	}
	public void setModRed(final float mod) {
		super.getTextGroup().setModRed(mod);
	}
	public void setModRGB(final float... mods) {
		super.getTextGroup().setModRed(mods[0]);
		super.getTextGroup().setModGreen(mods[1]);
		super.getTextGroup().setModBlue(mods[2]);
	}
	public void setModRGBA(final float... mods) {
		super.getTextGroup().setModRed(mods[0]);
		super.getTextGroup().setModGreen(mods[1]);
		super.getTextGroup().setModBlue(mods[2]);
		super.getTextGroup().setModAlpha(mods[3]);

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setPosition(final double x, final double y, final double z) {
		if (super.isDebug()) {
			System.out.println("setPosition");
		}
		boolean mustPositionText = false;
		if (super.getPosition() == null) {
			mustPositionText = true;
		}
		if (!mustPositionText 
				&& !super.getPosition().equals(x, y, z)) {
			super.getTextGroup().setFloatStoreNumber(0);
			super.getTextGroup().getPosition().setZ(
					z + GlobalConstants.CHILD_STEP);
		}
		super.setPositionExclusive(x, y, z);
		positionBorders();
		if (super.getSprite() != null) {
			double xs = x;
			double ys = y;
			double zs = z;
			if (super.isDebug()) {
				System.out.println(this+" x1=" + xs);
			}
			if (super.getBorder() != null) {
				xs += super.getBorder().getInsets().left;
				ys += super.getBorder().getInsets().bottom;
			}
			if (super.isDebug()) {
				System.out.println(this+" x2=" + xs);
			}
			int innerLeftInset = 0, innb = 0;
			if (highlightBorder != null) {
				innerLeftInset = highlightBorder.getInsets().left;
				innb = highlightBorder.getInsets().bottom;
			}
			if (super.isDebug()) {
				System.out.println(this+" innerLeftInset=" + innerLeftInset);
			}
			if (selectBorder != null) {
				innerLeftInset = Math.max(innerLeftInset,
						selectBorder.getInsets().left);
				innb = Math.max(innb,
						selectBorder.getInsets().bottom);
			}
			xs += innerLeftInset;
			ys += innb;
			if (super.isDebug()) {
				System.out.println(this+" x3=" + xs);
			}
			xs += super.getInsets().left;
			ys += super.getInsets().bottom;
			if (super.isDebug()) {
				System.out.println(this+" x4=" + xs);
			}
			super.getSprite().setPosition(xs, ys, z + GlobalConstants.CHILD_STEP * 0.01d);
		}
		if (mustPositionText) {
			try {
				positionText();
			} catch (Exception ex) {
				JOGLErrorHandler.getInstance().fatalError(ex);
			}
		}
		hotspot = null;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setPreferredSize(final int width, final int height) {
		preferredSize.width = width;
		preferredSize.height = height;
		int pWidth = width;
		// set border sizes based on order
		switch (borderPrecedence) {
		case GuiComponent.BORDER_FIRST:
			int internalW = 0,
			internalH = 0;
			if (super.getBorder() != null) {
				super.getBorder().setPreferredSize(width, height);
				internalW = super.getBorder().getInsets().left
						+ super.getBorder().getInsets().right;
				internalH = super.getBorder().getInsets().top
						+ super.getBorder().getInsets().bottom;
			}
			if (highlightBorder != null) {
				highlightBorder.setPreferredSize(width - internalW,
						height - internalH);
			}
			if (selectBorder != null) {
				selectBorder.setPreferredSize(width - internalW,
						height - internalH);
			}
			break;
		default:
			internalW = 0;
			internalH = 0;
			if (highlightBorder != null) {
				highlightBorder.setPreferredSize(width, height);
				internalW = highlightBorder.getInsets().left
						+ highlightBorder.getInsets().right;
				internalH = highlightBorder.getInsets().top
						+ highlightBorder.getInsets().bottom;
			}
			if (selectBorder != null) {
				selectBorder.setPreferredSize(width, height);
				internalW = Math.max(internalW,
						selectBorder.getInsets().left
								+ selectBorder.getInsets().right);
				internalH = Math.max(internalH,
						selectBorder.getInsets().top
								+ selectBorder.getInsets().bottom);
			}
			if (super.getBorder() != null) {
				super.getBorder().setPreferredSize(width - internalW,
						height - internalH);
			}
			break;
		}
		if (super.getBorder() != null) {
			pWidth -= super.getBorder().getInsets().left;
			pWidth -= super.getBorder().getInsets().right;
		}
		if (selectBorder != null) {
			pWidth -= selectBorder.getInsets().left;
			pWidth -= selectBorder.getInsets().right;
		}
		if (highlightBorder != null) {
			pWidth -= highlightBorder.getInsets().left;
			pWidth -= highlightBorder.getInsets().right;
		}
		pWidth -= super.getInsets().left;
		pWidth -= super.getInsets().right;
		super.setPreferredWidth(pWidth);
		try {
			sizeText();
			positionText();
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setSelectable(final boolean isSelectable) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setSelectBorder(final GuiBorder border) {
		selectBorder = border;
		preferredSize.width = 0;
		preferredSize.height = 0;
		getPreferredSize();
	}
	public void setSelected(final boolean val) {
		selected = val;
	}
}
